﻿//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Microsoft Public License.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace AstoriaOverAstoriaTests.CustomersModel
{
    using System;
    using System.Collections.Generic;
    using System.Data.Services;
    using System.Linq;
    using AstoriaOverAstoria;

    public class Customer
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public Customer BestFriend { get; set; }
        public List<Customer> Friends { get; set; }
        public bool? NullableBoolean { get; set; }
    }

    public class BigObject
    {
        public int ID { get; set; }

        public int IntegerProperty0 { get; set; }
        public int IntegerProperty1 { get; set; }
        public int IntegerProperty2 { get; set; }
        public int IntegerProperty3 { get; set; }
        public int IntegerProperty4 { get; set; }
        public int IntegerProperty5 { get; set; }
        public int IntegerProperty6 { get; set; }
        public int IntegerProperty7 { get; set; }
        public int IntegerProperty8 { get; set; }
        public int IntegerProperty9 { get; set; }

        public string StringProperty0 { get; set; }
        public string StringProperty1 { get; set; }
        public string StringProperty2 { get; set; }
        public string StringProperty3 { get; set; }
        public string StringProperty4 { get; set; }
        public string StringProperty5 { get; set; }
        public string StringProperty6 { get; set; }
        public string StringProperty7 { get; set; }
        public string StringProperty8 { get; set; }
        public string StringProperty9 { get; set; }
    }

    public class Animal
    {
        public int ID { get; set; }
        public Animal Related { get; set; }
        public List<Animal> SameKindAnimals { get; set; }
    }

    public class Cat : Animal
    {
        public string FurColor { get; set; }
    }

    public class FamousCat : Cat
    {
        public string Name { get; set; }
    }

    public class CustomDataContext
    {
        private static List<Customer> customers;
        private static List<BigObject> bigObjects;
        private static List<Animal> animals;

        static CustomDataContext()
        {
            customers = new List<Customer>();
            bigObjects = new List<BigObject>();
            animals = new List<Animal>();

            PopulateData();
        }

        private static void PopulateData()
        {
            customers.Add(new Customer()
            {
                ID = 0,
                Name = "Customer 0",
                BestFriend = null,
                Friends = new List<Customer>(),
                NullableBoolean = false
            });

            customers.Add(new Customer()
            {
                ID = 1,
                Name = "Customer 1",
                BestFriend = null,
                Friends = new List<Customer>(),
                NullableBoolean = true
            });

            customers.Add(new Customer()
            {
                ID = 2,
                Name = "Customer 2",
                BestFriend = null,
                Friends = new List<Customer>(),
                NullableBoolean = true
            });

            customers.Add(new Customer()
            {
                ID = 3,
                Name = null,
                BestFriend = null,
                Friends = new List<Customer>(),
                NullableBoolean = null
            });

            customers[1].BestFriend = customers[0];
            customers[1].Friends.Add(customers[0]);

            customers[2].BestFriend = customers[1];
            customers[2].Friends.Add(customers[0]);
            customers[2].Friends.Add(customers[1]);

            bigObjects.Add(new BigObject()
            {
                ID = 0,
                IntegerProperty0 = 0,
                IntegerProperty1 = 1,
                IntegerProperty2 = 2,
                IntegerProperty3 = 3,
                IntegerProperty4 = 4,
                IntegerProperty5 = 5,
                IntegerProperty6 = 6,
                IntegerProperty7 = 7,
                IntegerProperty8 = 8,
                IntegerProperty9 = 9,
                StringProperty0 = "String0",
                StringProperty1 = "String1",
                StringProperty2 = "String2",
                StringProperty3 = "String3",
                StringProperty4 = "String4",
                StringProperty5 = "String5",
                StringProperty6 = "String6",
                StringProperty7 = "String7",
                StringProperty8 = "String8",
                StringProperty9 = "String9"
            });

            animals.Add(new Animal()
            {
                ID = 0,
                SameKindAnimals = new List<Animal>()
            });

            animals.Add(new Cat()
            {
                ID = 1,
                SameKindAnimals = new List<Animal>(),
                FurColor = "black"
            });

            animals.Add(new FamousCat()
            {
                ID = 2,
                SameKindAnimals = new List<Animal>(),
                FurColor = "brown",
                Name = "Garfield"
            });

            animals[1].Related = animals[0];
            animals[1].SameKindAnimals.Add(animals[0]);

            animals[2].Related = animals[1];
            animals[2].SameKindAnimals.Add(animals[1]);
            animals[2].SameKindAnimals.Add(animals[0]);
        }

        public IQueryable<Customer> Customers
        {
            get { return customers.AsQueryable(); }
        }

        public IQueryable<BigObject> BigObjects
        {
            get { return bigObjects.AsQueryable(); }
        }

        public IQueryable<Animal> Animals
        {
            get { return animals.AsQueryable(); }
        }
    }

    public class CustomAoAService : AoATestService<AstoriaOverAstoriaContext>
    {
        protected override AstoriaOverAstoriaContext CreateDataSource()
        {
            var metadataMapping = new MetadataMapping("AOA.CustomersModel");

            metadataMapping.MapResourceSet("Customers", typeof(Customer));
            metadataMapping.MapResourceSet("BigObjects", typeof(BigObject));
            metadataMapping.MapResourceSet("Animals", typeof(Animal));

            return AoATestContext<CustomDataContext>.CreateContext(metadataMapping);
        }

        public override System.Type UnderlyingServiceType
        {
            get { return typeof(CustomDataContext); }
        }

        public override string PrepareRequestUri(string uri)
        {
            return uri.Replace("AstoriaOverAstoriaTests.CustomersModel", "AOA.CustomersModel");
        }
    }
}
